#include "../token.h"
#include "matcher.h"
#include "../ast/ast_def.h"
#include "../ast/ast_function.h"
#include "../logger.h"
#include <set>

Matcher::Matcher(TokenReader* reader) : reader(reader) {
	reader->nextToken();
	symbolTable = new SymbolTable();
}

Symbol Matcher::readNext() {
	reader->logCurToken();
	reader->nextToken();
	return reader->cur.symbol;
}

void Matcher::logError(const std::string& cause, const std::set<Symbol>& jumpTo) {
	log_error(1, cause, reader->getLineCnt(), reader->getPos());
	if (!jumpTo.empty()) {
		while (!jumpTo.count(reader->curToken().symbol) && reader->curToken().symbol != ENDFILE) {
			reader->nextToken();
		}
	}
	error = true;
}

void Matcher::logError(const std::string& cause, const std::set<Symbol>& jumpAfter, const std::set<Symbol>& jumpTo) {
	log_error(1, cause, reader->getLineCnt(), reader->getPos());
	if (!jumpTo.empty() || !jumpAfter.empty())
		for (;;) {
			if (reader->curToken().symbol == ENDFILE || jumpTo.count(reader->curToken().symbol)) {
				break;
			}
			if (jumpAfter.count(reader->cur.symbol)) {
				reader->nextToken();
				break;
			}
			reader->nextToken();
		}
	error = true;
}

template<typename T>
inline T* Matcher::addNode(T* node) {
	if (node == nullptr)
		return node;

	auto astNode = (ASTNode*)node;
	astNode->setLine(reader->getPreLineCnt());
	astNode->setPos(reader->getPrePos());
	astNode->addToTable(symbolTable);
	astNode->linkToTable(symbolTable);
	if(!astNode->checkError(symbolTable))error = true;
	return node;
}


ProgramNode* Matcher::createProgramNode() {
	Token& t = reader->cur;
	CnstListNode* cnst = nullptr;
	VarListNode* var = nullptr;
	if (t.symbol == CONSTTK) cnst = createCnstListNode();
	if (t.symbol == INTTK || t.symbol == CHARTK) {
		reader->nextToken();
		reader->nextToken();
		bool x = t.symbol == LPARENT;
		reader->back();
		reader->back();
		if (!x)var = createVarListNode(true);
	}
	std::vector<FunctionNode*> funcs;
	MainNode* mainNode;
	while (t.symbol != ENDFILE) {
		if (t.symbol == VOIDTK) {
			reader->nextToken();
			if (t.symbol == MAINTK) {
				reader->back();
				break;
			}
			reader->back();
			funcs.push_back((FunctionNode*)createFunctionVoidNode());
		}
		else if (t.symbol == INTTK || t.symbol == CHARTK) {
			funcs.push_back(createFunctionNode());
		}
		else logError("expected int/char/void", { INTTK, CHARTK, VOIDTK });
	}

	if (t.symbol == ENDFILE) {
		logError("missing main()", {});
		return nullptr;
	}
	mainNode = createMainNode();
	if (t.symbol != ENDFILE)logError("missing main()", {});
	Log << "<程序>" << std::endl;
	return addNode(new ProgramNode(cnst, var, funcs, mainNode));
}

CnstListNode* Matcher::createCnstListNode() {
	Token& t = reader->cur;
	if (t.symbol != CONSTTK)Log_E << "inner_ERR" << std::endl;
	std::vector<CnstDefNode*> list;
	while (t.symbol == CONSTTK) {
		readNext();
		list.push_back(createCnstDefNode());
		if (t.symbol != SEMICN) {
			logError("missing ;", {});
			log_error2('k', reader->getPreLineCnt());
		}
		else readNext();
	}
	Log << "<常量说明>" << std::endl;
	return addNode(new CnstListNode(list));
}

CnstDefNode* Matcher::createCnstDefNode() {
	Token& t = reader->cur;
	bool isInt = t.symbol == INTTK;
	std::vector<std::pair<std::string, int>> vec;
	if (t.symbol != INTTK && t.symbol != CHARTK) {
		logError("Unknown type. Expected: int/char.", { SEMICN, RBRACE });
		return nullptr;
	}
	do {
		if (readNext() != IDENFR) {
			logError("Bad identifier", { SEMICN, RBRACE });
			return nullptr;
		}
		auto s = t.string;
		if (readNext() != ASSIGN) goto err;
		readNext();
		if (isInt) {
			auto node = createIntNode();
			if (node != nullptr)vec.emplace_back(s, node->dat);
			else goto err;
		}
		else if (t.symbol == CHARCON) {
			vec.emplace_back(s, t.data.c);
			readNext();
		}
		else goto err;

	} while (t.symbol == COMMA);

	Log << "<常量定义>" << std::endl;
	return addNode(new CnstDefNode(isInt, vec));

err:
	logError("cnst definition err", { SEMICN });
	return nullptr;
}


IntNode* Matcher::createIntNode() {
	Token& t = reader->cur;
	bool p = true;
	if (t.symbol == MINU) p = false, readNext();
	else if (t.symbol == PLUS)readNext();
	if (t.symbol != INTCON)
		goto err;
	IntNode* node;
	node = new IntNode(p ? t.data.i : -t.data.i);
	readNext();
	Log << "<整数>" << std::endl;
	return addNode(node);
err:
	logError("integer value error", { COMMA, SEMICN });
	return nullptr;
}

FunctionHeadNode* Matcher::createFunctionHeadNode() {
	Token& t = reader->cur;
	if (t.symbol == INTTK || t.symbol == CHARTK) {
		bool isInt = t.symbol == INTTK;
		if (readNext() != IDENFR) {
			logError("Bad identifier", { LPARENT, RBRACE });
			return nullptr;
		}
		std::string s = t.string;
		readNext();
		Log << "<声明头部>" << std::endl;
		return addNode(new FunctionHeadNode(isInt, s));
	}
	logError("Unknown data type. ", { LPARENT, RBRACE });
	return nullptr;
}


CnstNode* Matcher::createCnstNode() {
	Token& t = reader->cur;
	if (t.symbol == CHARCON) {
		auto node = new CnstNode(t.data.c);
		readNext();
		Log << "<常量>" << std::endl;
		return addNode(node);
	}
	int i = createIntNode()->dat;
	Log << "<常量>" << std::endl;
	return new CnstNode(i);
	//logError("expected interger/char const", {COMMA, RBRACE, SEMICN});
	//return addNode(new CnstNode('\0'));
}

VarListNode* Matcher::createVarListNode(bool checkFunction) {
	Token& t = reader->cur;
	if (t.symbol != INTTK && t.symbol != CHARTK) {
		logError("inner error, expected int/char", { ENDFILE });
		return nullptr;
	}
	std::vector<VarDefNode*> list;
	while (t.symbol == INTTK || t.symbol == CHARTK) {
		if (checkFunction) {
			reader->nextToken();
			reader->nextToken();
			bool x = t.symbol == LPARENT;
			reader->back();
			reader->back();
			if (x) break;
		}
		list.push_back(createVarDefNode());
		if (t.symbol != SEMICN) {
			logError("missing ;", {});
            log_error2('k', reader->getPreLineCnt());
		}
		else readNext();
	}
	Log << "<变量说明>" << std::endl;
	return addNode(new VarListNode(list));
}

VarDefNode* Matcher::createVarDefNode() {
	Token& t = reader->cur;
	if (t.symbol != INTTK && t.symbol != CHARTK) {
		logError("inner error, expected int/char", { ENDFILE });
		return nullptr;
	}
	bool isInt = t.symbol == INTTK;
	std::vector<Var_data*> vector;
	bool init = false;
	do {
		if (readNext() != IDENFR) {
			logError("Bad identifier", { SEMICN });
			continue;
		}
		auto name = t.string;
		readNext();
		int dimension = 0;
		int size[2] = {};
		for (int i : {0, 1}) {
			if (t.symbol == LBRACK) {
				dimension++;
				if (readNext() != INTCON)logError("Bad dimension value", { RBRACK, COMMA, SEMICN });
				else size[i] = t.data.i;
				if (readNext() != RBRACK)logError("Missing ]", {}), log_error2('m', reader->getLineCnt());
				else readNext();
			}
		}
		if (t.symbol == ASSIGN) {
			if (!init && !vector.empty()) logError("mixed init & non-init definition", {});
			readNext();
			init = true;
			std::vector<int> arr;
			switch (dimension) {
			case 0: {
                CnstNode *cnstNode = createCnstNode();
                //变量定义及初始化和switch语句中的<常量>必须与声明的类型一致
                if (cnstNode->isInt != isInt) logError("data type not match", {}), log_error2('o', reader->getLineCnt());
                vector.push_back(new Var_data(name, cnstNode->val));
            }
				break;
			case 1:
				arr = readArr(isInt);
				//数组初始化个数不匹配
                if (arr.size() != size[0]) {
                    logError("array size does not match its declaration.", {});
                    log_error2('n', reader->getLineCnt());
                }
				vector.push_back(new Var_data(name, size, arr));
				break;
			default:
				auto arr2 = readArr2(isInt);
                //数组初始化个数不匹配
                if (arr2.size() != size[0]) {
                    logError("array size does not match its declaration.", {});
                    log_error2('n', reader->getLineCnt());
                } else {
                    for (const std::vector<int> &arr1 : arr2){
                        if(arr1.size() != size[1]){
                            logError("array size does not match its declaration.", {});
                            log_error2('n', reader->getLineCnt());
                        }
                    }
                }
				vector.push_back(new Var_data(name, size, arr2));
				break;
			}
		}
		else {
			vector.push_back(new Var_data(name, dimension, size));
			if (init) logError("mixed init & non-init definition", {});
		}
	} while (t.symbol == COMMA);
	if (init) {
		Log << "<变量定义及初始化>" << std::endl;
		Log << "<变量定义>" << std::endl;
		auto ret = new VarDefInitNode(isInt, vector);
		return addNode(ret);
	}
	else {
		Log << "<变量定义无初始化>" << std::endl;
		Log << "<变量定义>" << std::endl;
		auto re = new VarDefNode(isInt, vector);
		return addNode(re);
	}
}

inline std::vector<int> Matcher::readArr(bool isInt) {
	std::vector<int> ret;
	Token& t = reader->cur;
	if (t.symbol != LBRACE) {
		logError("expected {", { COMMA, SEMICN });
		return ret;
	}
	do {
		readNext();
		CnstNode* cnstNode = createCnstNode();
		//变量定义及初始化和switch语句中的<常量>必须与声明的类型一致
		if (cnstNode->isInt != isInt) logError("data type not match", {}), log_error2('o', reader->getLineCnt());
		else ret.push_back(cnstNode->val);
		delete cnstNode;
	} while (t.symbol == COMMA);
	if (t.symbol != RBRACE) {
		logError("expected }", { SEMICN });
		return ret;
	}
	readNext();
	return ret;
}

inline std::vector<std::vector<int>> Matcher::readArr2(bool isInt) {
	std::vector<std::vector<int>> ret;
	Token& t = reader->cur;
	if (t.symbol != LBRACE) {
		logError("expected {", { SEMICN });
		return ret;
	}
	do {
		ret.emplace_back();
		if (readNext() != LBRACE) {
			logError("expected {", { SEMICN });
			return ret;
		}
		do {
			readNext();
			CnstNode* cnstNode = createCnstNode();
			//变量定义及初始化和switch语句中的<常量>必须与声明的类型一致
			if (cnstNode->isInt != isInt) logError("data type not match", {}), log_error2('o', reader->getLineCnt());
			ret.back().push_back(cnstNode->val);
		} while (t.symbol == COMMA);
		if (t.symbol != RBRACE) {
			logError("expected }", { SEMICN });
			return ret;
		}
		readNext();
	} while (t.symbol == COMMA);
	if (t.symbol != RBRACE) {
		logError("expected }", { SEMICN });
		return ret;
	}
	readNext();
	return ret;
}

FunctionVoidNode* Matcher::createFunctionVoidNode() {
	Token& t = reader->cur;
	if (t.symbol != VOIDTK || readNext() != IDENFR) {
		logError("inner error: void funciton", {});
		return nullptr;
	}
	curFuncType = 0;
	auto name = t.string;
	ParamsNode* params;
	BodyNode* body;
	if (readNext() != LPARENT)logError("expected (", { LBRACE, RBRACE });
	else {
		readNext();
	}

	symbolTable->pushStack();
	params = createParamsNode();
	if (params != nullptr) params->putVoidFuncToTable(symbolTable, name);
	if (t.symbol != RPARENT)logError("missing )", { LBRACE, RBRACE }), log_error2('l', reader->getLineCnt());
	else readNext();
	if (t.symbol != LBRACE)logError("expected {", { LBRACE }, { RBRACE });
	else readNext();
	body = createBodyNode();
	symbolTable->popStack();
	if (params != nullptr) params->putVoidFuncToTable(symbolTable, name);
	if (t.symbol != RBRACE)logError("expected }", { RBRACE });
	if (t.symbol != ENDFILE) readNext();
	Log << "<无返回值函数定义>" << std::endl;
	return addNode(new FunctionVoidNode(name, params, body));
}

FunctionNode* Matcher::createFunctionNode() {
    FunctionHeadNode *head = createFunctionHeadNode();
    curFuncType = head->retInt ? 2 : 1;
    ParamsNode *params = nullptr;
    BodyNode *body = nullptr;
    Token &t = reader->cur;
    if (t.symbol != LPARENT)logError("expected (", {});
    else readNext();
    symbolTable->pushStack();
    params = createParamsNode();
    if (params != nullptr) params->putFunctionToTable(symbolTable, head);
    if (t.symbol != RPARENT) { logError("missing )", {}), log_error2('l', reader->getLineCnt());
    } else readNext();
    if(t.symbol != LBRACE) { logError("expected {", { LBRACE }, { RBRACE });
    } else readNext();
	body = createBodyNode();
	symbolTable->popStack();
	if (params != nullptr) params->putFunctionToTable(symbolTable, head);
	if (t.symbol != RBRACE)logError("expected }", { RBRACE });
	if (t.symbol != ENDFILE)readNext();
	Log << "<有返回值函数定义>" << std::endl;
	return addNode(new FunctionNode(head, params, body));
}

BodyNode* Matcher::createBodyNode() {
	Token& t = reader->cur;
	CnstListNode* cnst = nullptr;
	VarListNode* var = nullptr;
	StatListNode* statements;
	if (t.symbol == CONSTTK) cnst = createCnstListNode();
	if (t.symbol == INTTK || t.symbol == CHARTK) {
		var = createVarListNode(false);
	}
	statements = createStatListNode();
	Log << "<复合语句>" << std::endl;
	return addNode(new BodyNode(cnst, var, statements));
}

ParamsNode* Matcher::createParamsNode() {
	std::vector<std::pair<bool, std::string>> params;
	Token& t = reader->cur;
	if (t.symbol != RPARENT) {
		do {
			bool isInt = t.symbol == INTTK;
			if (t.symbol != INTTK && t.symbol != CHARTK)
				logError("invalid type, expected int/char", { COMMA, RPARENT, LBRACE, RBRACE });
			else if (readNext() == IDENFR) {
				params.emplace_back(isInt, t.string);
				readNext();
			}
			else logError("invalid identifier", { COMMA, RPARENT, LBRACE, RBRACE });
			if (t.symbol == RPARENT || t.symbol == LBRACE || t.symbol == RBRACE)break;
			else if (t.symbol == COMMA) readNext();
			else if (t.symbol == INTTK || t.symbol == CHARTK)logError("missing ,", {});
			else logError("invalid token", { RPARENT, LBRACE, RBRACE });
		} while (t.symbol == INTTK || t.symbol == CHARTK);
	}
	Log << "<参数表>" << std::endl;
	return addNode(new ParamsNode(params));
}

MainNode* Matcher::createMainNode() {
    insideMain = true;
	Token& t = reader->cur;
	BodyNode* body;
	curFuncType = 0;
	if (t.symbol != VOIDTK)logError("inner_error:void main", {});
	if (readNext() != MAINTK)logError("inner_error:void main", {});
	if (readNext() != LPARENT)logError("expected (", {LBRACE});
	else if (readNext() != RPARENT)logError("missing )", {}),log_error2('l', reader->getLineCnt());
	if (readNext() != LBRACE)logError("expected {", {});
	else readNext();
	symbolTable->pushStack();
	body = createBodyNode();
    symbolTable->popStack();
	if (t.symbol != RBRACE)logError("missing }", {});
	else readNext();
	Log << "<主函数>" << std::endl;
	insideMain = false;
	return addNode(new MainNode(body));
}

ExprNode* Matcher::createExprNode() {
	Token& t = reader->cur;
	bool plus = true;
	if (t.symbol == PLUS || t.symbol == MINU) {
		plus = t.symbol == PLUS;
		readNext();
	}
	std::vector<std::pair<bool, TermNode*>> terms;
	for (;;) {
		TermNode* node = createTermNode();
		terms.emplace_back(plus, node);
		plus = t.symbol == PLUS;
		if (t.symbol == PLUS || t.symbol == MINU) {
			readNext();
		}
		else break;
	}
	Log << "<表达式>" << std::endl;
	return addNode(new ExprNode(terms));
}

TermNode* Matcher::createTermNode() {

	Token& t = reader->cur;
	bool mult = true;
	std::vector<std::pair<bool, FactorNode*>> terms;
	for (;;) {
		FactorNode* node = createFactorNode();
		terms.emplace_back(mult, node);
		mult = t.symbol == MULT;
		if (t.symbol == MULT || t.symbol == DIV) {
			readNext();
		}
		else break;
	}
	Log << "<项>" << std::endl;
	return addNode(new TermNode(terms));
}

FactorNode* Matcher::createFactorNode() {
#define LogF Log<<"<因子>"<<std::endl
	Token& t = reader->cur;
	FactorNode* f; IntNode* intNode;
	int val;
	char c;
	switch (t.symbol) {
	case IDENFR:
		ID_Type type;
		if(!symbolTable->containsSymbol(t.string)){
            logError("undefined identifier", {  });
            log_error2('c', reader->getLineCnt());//引用未定义的名字
            //return nullptr;
		}
		type = symbolTable->getDiscriptions(t.string).type;

        reader->nextToken();
        bool call;
        call = reader->curToken().symbol == LPARENT;
        reader->back();
        if(!call){

            f = createIdentiferFactor();
            LogF;
            return f;
        } else {
			auto n = createFuncCallNode();
			LogF;
			return addNode(new FunctionCallFactor(n));
		}
		logError("invalid factor", { PLUS, MINU, MULT, DIV, SEMICN, RPARENT, RBRACE });
		return nullptr;
	case INTCON:
	case PLUS:
	case MINU:
		intNode = createIntNode();
		val = intNode->dat;
		delete intNode;
		LogF;
		return addNode(new FactorNode(val));
	case CHARCON:
		c = t.data.c;
		readNext();
		LogF;
		return addNode(new FactorNode(c));
	case LPARENT:
		readNext();
		f = createExprNode();
		if (t.symbol != RPARENT)logError("missing )", {}),  log_error2('l', reader->getLineCnt());
		else readNext();
		LogF;
		return f;
	default:
		logError("invalid factor", { PLUS, MINU, MULT, DIV, SEMICN, RPARENT, RBRACE });
		return nullptr;
	}
#undef Log
}

StatNode* Matcher::createStatNode() {
#define Log Log<<"<语句>"<<std::endl
	Token& t = reader->cur;
	StatNode* n = nullptr;
	switch (t.symbol) {
	case FORTK:
		n = createForNode();
		Log;
		return n;
	case WHILETK:
		n = createWhileNode();
		Log;
		return n;
	case IFTK:
		n = createIfNode();
		Log;
		return n;
	case IDENFR:
        if(!symbolTable->containsSymbol(t.string)){
            logError("undefined identifier",  { }, {});
            log_error2('c', reader->getLineCnt());//引用未定义的名字
            //return nullptr;
        }
		ID_Type type;
		type = symbolTable->getDiscriptions(t.string).type;
		reader->nextToken();
		bool assign;
		assign = reader->curToken().symbol != LPARENT;
		reader->back();
		if(assign) n = createAssignNode();
		else if (type == ID_VOID) n = createVoidCallNode();
		else  n = createFuncCallNode();
		break;
	case SCANFTK:
		n = createScanfNode();
		break;
	case PRINTFTK:
		n = createPrintfNode();
		break;
	case SWITCHTK:
		n = createSwitchNode();
		Log;
		return n;
	case SEMICN:
		break;
	case RETURNTK:
		n = createReturnNode();
		break;
	case LBRACE:
		readNext();
		n = createStatListNode();
		if (t.symbol != RBRACE) logError("missing }", {});
		else readNext();
		Log;
		return n;
	default:
		logError("invalid statement", { SEMICN }, { RBRACE });
		return nullptr;
	}
	if (reader->curToken().symbol == SEMICN) readNext();
	else logError("missing ;", {}), log_error2('k', reader->getPreLineCnt());
	Log;
	return n;
#undef Log
}

AssignNode* Matcher::createAssignNode() {
	Token& t = reader->cur;
	auto factor = createIdentiferFactor();
	if (t.symbol != ASSIGN) {
		logError("expected assign statement", { SEMICN, RBRACE });
		return nullptr;
	}
	readNext();
	auto val = createExprNode();
	Log << "<赋值语句>" << std::endl;
	return addNode(new AssignNode(factor, val));
}

IfNode* Matcher::createIfNode() {
	Token& t = reader->cur;
	if (t.symbol != IFTK) {
		logError("inner error : if", { RBRACE }, { ENDFILE, SEMICN });
		return nullptr;
	}
	if (readNext() != LPARENT) logError("expected (", {});
	else readNext();
	auto conditionNode = createConditionNode();
	if (t.symbol != RPARENT) logError("expected )", {}), log_error2('l', reader->getLineCnt());
	else readNext();
	auto ifStatement = createStatNode();
	if (t.symbol == ELSETK) {
		readNext();
		auto elseStatement = createStatNode();
		Log << "<条件语句>" << std::endl;
		return addNode(new IfNode(conditionNode, ifStatement, elseStatement));
	}
	Log << "<条件语句>" << std::endl;
	return addNode(new IfNode(conditionNode, ifStatement));
}

ConditionNode* Matcher::createConditionNode() {
	auto exp1 = createExprNode();
	Symbol op = reader->cur.symbol;
	if (!isRelationSymbol(op)) {
		logError("bad relation operator", { SEMICN, RBRACE, RPARENT });
		return nullptr;
	}
	readNext();
	auto exp2 = createExprNode();
	Log << "<条件>" << std::endl;
	return addNode(new ConditionNode(exp1, exp2, op));
}

ForNode* Matcher::createForNode() {
	std::string initVar, alterVal1, alterVal2;
	ExprNode* initialVal;
	ConditionNode* condition;
	bool positive = true;
	int step = 0;
	StatNode* statements;
	Token& t = reader->cur;
	if (t.symbol != FORTK) {
		logError("inner error : for", {});
		return nullptr;
	}
	if (readNext() != LPARENT)logError("expected (", {}), reader->back();
	if (readNext() != IDENFR)logError("bad identifer", { ASSIGN, SEMICN, RPARENT, RBRACE }), reader->back();
	else initVar = t.string;
    if(!symbolTable->containsSymbol(t.string)){
        logError("undefined identifier",  {});
        log_error2('c', reader->getLineCnt());//引用未定义的名字
        return nullptr;
    }
	if (readNext() != ASSIGN) logError("expected =", {});
	else readNext();
	initialVal = createExprNode();
	if (t.symbol != SEMICN)logError("missing ;", {}), log_error2('k', reader->getLineCnt());
	else readNext();
	condition = createConditionNode();
	if (t.symbol != SEMICN){logError("missing ;", {}), log_error2('k', reader->getLineCnt()); reader->back();}
	if (readNext() != IDENFR){logError("bad identifer", { ASSIGN, SEMICN, RPARENT, RBRACE }); reader->back();}
	else alterVal1 = t.string;
    if(!symbolTable->containsSymbol(t.string)){
        logError("undefined identifier",  {});
        log_error2('c', reader->getLineCnt());//引用未定义的名字
        return nullptr;
    }
	if (readNext() != ASSIGN) logError("expected =", {}), reader->back();
	if (readNext() != IDENFR)logError("bad identifer", { ASSIGN, SEMICN, RPARENT, RBRACE });
	else alterVal2 = t.string;
    if(!symbolTable->containsSymbol(t.string)){
        logError("undefined identifier",  {});
        log_error2('c', reader->getLineCnt());//引用未定义的名字
        return nullptr;
    }
	if (readNext() == PLUS) positive = true, readNext();
	else if (t.symbol == MINU) positive = false, readNext();
	else logError("expected +/-", {});
	if (t.symbol != INTCON) logError("bad step length", {});
	else step = positive ? t.data.i : -t.data.i, readNext(), Log << "<步长>" << std::endl;
	if (t.symbol != RPARENT)logError("expected )", {}), log_error2('l', reader->getLineCnt());
	else readNext();
	statements = createStatNode();
	Log << "<循环语句>" << std::endl;
	return addNode(new ForNode(initVar, alterVal1, alterVal2, initialVal, condition, step, statements));
}

WhileNode* Matcher::createWhileNode() {
	ConditionNode* condition;
	StatNode* statements;
	if (reader->cur.symbol != WHILETK) {
		logError("inner error : while", {});
		return nullptr;
	}
	if (readNext() != LPARENT)logError("expected (", {});
	else readNext();
	condition = createConditionNode();
	if (reader->cur.symbol != RPARENT)logError("expected )", {  }, {  }), log_error2('l', reader->getLineCnt());
	else readNext();
	statements = createStatNode();
	Log << "<循环语句>" << std::endl;
	return addNode(new WhileNode(condition, statements));
}

SwitchNode* Matcher::createSwitchNode() {
	ExprNode* expr;
	SwitchTableNode* cases;
	if (reader->cur.symbol != SWITCHTK) {
		logError("inner error : switch", {});
		return nullptr;
	}
	if (readNext() != LPARENT)logError("expected (", {});
	else readNext();
	expr = createExprNode();
	if (reader->cur.symbol != RPARENT)logError("expected )", {}), log_error2('l', reader->getLineCnt());
	else readNext();
	if (reader->cur.symbol != LBRACE)logError("expected {", {});
	else readNext();
	cases = createSwitchTableNode(expr->isReturnInt());
	if (reader->cur.symbol != RBRACE)logError("expected }", { RBRACE }, {});
	else readNext();
	Log << "<情况语句>" << std::endl;
	return addNode(new SwitchNode(expr, cases));
}

SwitchTableNode* Matcher::createSwitchTableNode(bool isInt) {
	std::map<int, StatNode*> cases;
	StatNode* defalutStatement;
	Token& t = reader->cur;
	while (t.symbol == CASETK) {
		readNext();
		CnstNode* cnst = createCnstNode();
		//<常量>类型不一致
		if(cnst->isInt != isInt) logError("case data type mismatch with switch", {}), log_error2('o', reader->getLineCnt());
		if (reader->cur.symbol != COLON)logError("expected :", {});
		else readNext();
		StatNode* statment = createStatNode();
		cases[cnst->val] = statment;
		Log << "<情况子语句>" << std::endl;
	}
	if (cases.empty())logError("missing cases", {});
	Log << "<情况表>" << std::endl;
	//缺少缺省语句
	if (t.symbol != DEFAULTTK)logError("missing defalut", { RBRACE, SEMICN }), log_error2('p', reader->getLineCnt());
	else if (readNext() != COLON)logError("expected :", {});
	else readNext();
	defalutStatement = createStatNode();
	Log << "<缺省>" << std::endl;
	return addNode(new SwitchTableNode(cases, defalutStatement));
}

FuncCallNode* Matcher::createFuncCallNode() {
	Token& t = reader->cur;
	if (t.symbol != IDENFR) {
		logError("inner error : function call", {});
		return nullptr;
	}
    if(!symbolTable->containsSymbol(t.string)){
        logError("undefined identifier",  { });
        log_error2('c', reader->getLineCnt());//引用未定义的名字
    }
	std::string name = t.string;
	if (readNext() != LPARENT)logError("expected (", {});
	else readNext();
	FuncCallParamsNode* paramsNode = createFuncCallParamsNode();
	if (reader->cur.symbol != RPARENT)logError("expected )", {}), log_error2('l', reader->getLineCnt());
	else readNext();
	Log << "<有返回值函数调用语句>" << std::endl;
	return addNode(new FuncCallNode(name, paramsNode));
}

VoidCallNode* Matcher::createVoidCallNode() {
	Token& t = reader->cur;
	if (t.symbol != IDENFR) {
		logError("inner error : function call", {});
		return nullptr;
	}
    if(!symbolTable->containsSymbol(t.string)){
        logError("undefined identifier",   {  });
        log_error2('c', reader->getLineCnt());//引用未定义的名字
    }
	std::string name = t.string;
	if (readNext() != LPARENT)logError("expected (", {});
	else readNext();
	FuncCallParamsNode* paramsNode = createFuncCallParamsNode();
	if (reader->cur.symbol != RPARENT)logError("missing )", {}), log_error2('l', reader->getLineCnt());
	else readNext();
	Log << "<无返回值函数调用语句>" << std::endl;
	return addNode(new VoidCallNode(name, paramsNode));
}

FuncCallParamsNode* Matcher::createFuncCallParamsNode() {
	std::vector<ExprNode*> exprs;
	Token& t = reader->cur;
	if (t.symbol == RPARENT) {
		Log << "<值参数表>" << std::endl;
		return addNode(new FuncCallParamsNode(exprs));
	}
	for (;;) {
		exprs.push_back(createExprNode());
		if (t.symbol != COMMA)break;
		readNext();
	}
	Log << "<值参数表>" << std::endl;
	return addNode(new FuncCallParamsNode(exprs));
}

StatListNode* Matcher::createStatListNode() {
	Token& t = reader->cur;
	std::vector<StatNode*> statements;
	symbolTable->pushStack();
	while (t.symbol != RBRACE && t.symbol != ENDFILE) {
		statements.push_back(createStatNode());
	}
	symbolTable->popStack();
	Log << "<语句列>" << std::endl;
	return addNode(new StatListNode(statements));
}

ScanfNode* Matcher::createScanfNode() {
	Token& t = reader->cur;
	if (t.symbol != SCANFTK) logError("inner error. scanf. ", { SEMICN, RBRACE });
	else if (readNext() != LPARENT) logError("expected (", { SEMICN, RBRACE });
	else if (readNext() != IDENFR) logError("invalid identifier", { SEMICN, RBRACE });
	else {
        std::string id = t.string;
        if(!symbolTable->containsSymbol(id)){
            logError("undefined identifier",   {});
            log_error2('c', reader->getLineCnt());//引用未定义的名字
            //return nullptr;
        }
		if (readNext() != RPARENT) logError("missing )", {}), log_error2('l', reader->getLineCnt());
		else readNext();
		Log << "<读语句>" << std::endl;
		return addNode(new ScanfNode(id));
	}
	return nullptr;

}

PrintfNode* Matcher::createPrintfNode() {
	Token& t = reader->cur;
	if (t.symbol != PRINTFTK) {
		logError("inner error : printf", {});
		return nullptr;
	}
	if (readNext() != LPARENT)logError("expected (", {});
	readNext();
	std::string str;
	ExprNode* expr = nullptr;
	if (t.symbol == STRCON) {
		str = t.string;
		if (readNext() == COMMA) {
			readNext();
			expr = createExprNode();
		}
		if (t.symbol != RPARENT)logError("missing )", {}), log_error2('l', reader->getLineCnt());
		else readNext();
		Log << "<写语句>" << std::endl;
		return addNode(expr == nullptr ? new PrintfNode(str) : new PrintfNode(str, expr));
	}
	expr = createExprNode();
	if (t.symbol != RPARENT)logError("missing )", {}), log_error2('l', reader->getLineCnt());
	else readNext();
	Log << "<写语句>" << std::endl;
	return addNode(new PrintfNode(expr));
}

ReturnNode* Matcher::createReturnNode() {
	if (reader->cur.symbol != RETURNTK) {
		logError("inner error : return", {});
		return nullptr;
	}
	if (readNext() == LPARENT) {
		readNext();
		if(reader->cur.symbol == RPARENT){
		    logError("return ( ? )", {});
		    log_error2(curFuncType == 0 ? 'g' : 'h' , reader->getLineCnt());
            readNext();
            return new BadReturnNode();
		}
		ExprNode* exprNode = createExprNode();
		int retval = exprNode == nullptr ? 0 : exprNode->isReturnInt() ? 2 : 1;
		if(retval != curFuncType){
            logError("return value type error", {});
            log_error2(curFuncType == 0 ? 'g' : 'h' , reader->getLineCnt());
		}
		if (reader->cur.symbol != RPARENT)logError("missing )", { }), log_error2('l', reader->getLineCnt());
		else readNext();
		Log << "<返回语句>" << std::endl;
		return addNode(new ReturnNode(exprNode, insideMain));
	}
	if(0 != curFuncType){
        logError("return value type error", {});
        log_error2(curFuncType == 0 ? 'g' : 'h' , reader->getLineCnt());
    }
	Log << "<返回语句>" << std::endl;
	return addNode(new ReturnNode(nullptr, insideMain));
}

IdentiferFactor* Matcher::createIdentiferFactor() {
	Token& t = reader->cur;
	if (t.symbol != IDENFR) {
		logError("inner error : identifier factor", {});
		return nullptr;
	}
	auto name = t.string;
    if(!symbolTable->containsSymbol(name)){
        logError("undefined identifier",   {});
        log_error2('c', reader->getLineCnt());//引用未定义的名字
        //return nullptr;
    }
	readNext();
	int dimension = 0;
	ExprNode* expr[2] = { nullptr, nullptr };
	for (int i : {0, 1}) {
		if (t.symbol == LBRACK) {
			readNext();
			dimension++;
			expr[i] = createExprNode();
			if (reader->cur.symbol != RBRACK)logError("Missing ]", {}), log_error2('m', reader->getLineCnt());
			else readNext();
		}
	}
	return addNode(new IdentiferFactor(name, dimension, expr[0], expr[1]));
}

bool Matcher::isError() const {
    return error;
}
